package avicit.bdp.dcs.desensitization.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dcs.desensitization.dao.DataMaskingPolicyDao;
import avicit.bdp.dcs.desensitization.dto.DataMaskingPolicyDto;
import avicit.bdp.dcs.utils.DcsConstants;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2021-08-02
 * @类说明：DataMaskingPolicyService
 * @修改记录：
 * @注意事项：
 * @主要功能：脱敏策略服务
 */
@Service
@Transactional
@DependsOn("springApplicationContext")
public class DataMaskingPolicyService extends BaseService<DataMaskingPolicyDao, DataMaskingPolicyDto> {
	private static final Logger logger = LoggerFactory.getLogger(DesensitizationRuleService.class);

	/**
	 * 脱敏策略DAO层对象
	 */
	@Autowired
	private DataMaskingPolicyDao dataMaskingPolicyDao;

	/**
	 * 获取系统用户名
	 */
	@Autowired
	private ConvertColumnClient convertColumnClient;

	/**
	 * 新建脱敏策略
	 *
	 * @param dataMaskingPolicyDto
	 * @return
	 */
	public void createDataMaskingPolicy(DataMaskingPolicyDto dataMaskingPolicyDto) {
		// step1:合法性检查
		CheckParaUtils.checkObjectValidity(dataMaskingPolicyDto, logger, "入参为null.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoType(), logger, "算法类型未配置.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoId(), logger, "脱敏算法ID未配置.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoName(), logger, ("脱敏算法名称未配置."));

		// step2:持久化
		savePolicy2Db(dataMaskingPolicyDto);
	}

	/**
	 * 修改脱敏策略
	 *
	 * @param dataMaskingPolicyDto
	 * @return
	 */
	public void updateDataMaskingPolicy(DataMaskingPolicyDto dataMaskingPolicyDto) {
		// step1:合法性检查
		CheckParaUtils.checkObjectValidity(dataMaskingPolicyDto, logger, "入参为null.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getId(), logger, "脱敏策略主键ID为null.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoType(), logger, "算法类型未配置.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoId(), logger, "脱敏算法ID未配置.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getAlgoName(), logger, "脱敏算法名称未配置.");

		// step2:查询脱敏策略
		DataMaskingPolicyDto queryRet = queryDataMaskingPolicy(dataMaskingPolicyDto.getId());

		// step3:更新脱敏策略
		updatePolicy2Db(dataMaskingPolicyDto, queryRet);
	}

	/**
	 * 移除脱敏策略；多个id使用英文逗号隔开
	 *
	 * @param dataMaskingPolicyDto
	 * @return
	 */
	public void deleteDataMaskingPolicy(DataMaskingPolicyDto dataMaskingPolicyDto) {
		// step1:合法性检查
		CheckParaUtils.checkObjectValidity(dataMaskingPolicyDto, logger, "入参为null.");
		CheckParaUtils.checkStringValidity(dataMaskingPolicyDto.getId(), logger, "脱敏策略主键ID为null.");

		String[] ids = dataMaskingPolicyDto.getId().trim().split(Constants.COMMA);
		for (String currId : ids) {
			deleteSingleDataMaskingPolicy(currId);
		}
	}

	/**
	 * 列举脱敏策略
	 *
	 * @param sort
	 * @param pageNo
	 * @param pageSize
	 * @param name
	 * @return
	 */
	public QueryRespBean<DataMaskingPolicyDto> listDataMaskingPolicy(Integer sort, Integer pageNo,
																	 Integer pageSize, String name) {
		// step1:构建排序参数
		QueryRespBean<DataMaskingPolicyDto> queryRespBean = new QueryRespBean<>();
		String orderField = buildOrderField(sort);
		String orderType = buildOrderType(sort);
		List<String> wordSecretList = ThreadContextHelper.getWordSecretList();
		com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);

		// step2: 分页查表
		Page<DataMaskingPolicyDto> policyList =
				this.dataMaskingPolicyDao.listDataMaskingPolicy(name, orderField, orderType, wordSecretList);
		queryRespBean.setResult(policyList);

		// step3:设置创建人中文名称
		List<DataMaskingPolicyDto> tmpPolicyList = policyList.getResult();
		if (tmpPolicyList != null) {
			for (DataMaskingPolicyDto policyDto : tmpPolicyList) {
				policyDto.setCreatedBy(getUserNameByIds(policyDto.getCreatedBy()));
			}
		}

		BdpLogUtil.log4Query(queryRespBean);
		return queryRespBean;
	}

	/**
	 * 查询脱敏策略详情
	 *
	 * @return
	 */
	public DataMaskingPolicyDto queryDataMaskingPolicyById(String id) {
		CheckParaUtils.checkStringValidity(id, logger, "脱敏策略主键ID为null.");
		DataMaskingPolicyDto dto = queryDataMaskingPolicy(id);
		BdpLogUtil.log4Query(dto);
		return dto;
	}

	/**
	 * 脱敏策略持久化到DB
	 *
	 * @param dataMaskingPolicyDto
	 */
	private void savePolicy2Db(DataMaskingPolicyDto dataMaskingPolicyDto) {
		// step1:持久化到DB
		dataMaskingPolicyDto.setId(ComUtil.getId());
		this.insert(dataMaskingPolicyDto);

		// step2:记录平台日志
		BdpLogUtil.log4Insert(dataMaskingPolicyDto);
	}

	/**
	 * 更新脱敏策略
	 *
	 * @param newDto
	 * @param oldDto
	 */
	private void updatePolicy2Db(DataMaskingPolicyDto newDto, DataMaskingPolicyDto oldDto) {
		// step1:持久化到DB
		this.updateByPrimaryKeySelective(newDto);

		// step2:记录平台日志
		BdpLogUtil.log4Update(newDto, oldDto);
	}

	/**
	 * 移除单个脱敏策略
	 *
	 * @param id
	 */
	private void deleteSingleDataMaskingPolicy(String id) {
		// step1:合法性检查
		CheckParaUtils.checkStringValidity(id, logger, "脱敏策略主键ID为null.");

		// step2:查询脱敏策略
		DataMaskingPolicyDto queryRet = queryDataMaskingPolicy(id);

		// step3:删除脱敏策略
		this.dataMaskingPolicyDao.deleteByPrimaryKey(id);

		// step4:记录平台日志
		BdpLogUtil.log4Delete(queryRet);
	}

	/**
	 * 根据主键ID查询脱敏策略
	 *
	 * @param id
	 * @return
	 */
	private DataMaskingPolicyDto queryDataMaskingPolicy(String id) {
		DataMaskingPolicyDto queryRet = this.dataMaskingPolicyDao.selectByPrimaryKey(id);
		CheckParaUtils.checkObjectValidity(queryRet, logger, String.format("查询脱敏策略失败，id=%s.", id));

		return queryRet;
	}

	/**
	 * 构建orderField
	 *
	 * @param sort
	 * @return
	 */
	private String buildOrderField(Integer sort) {
		// 排序，1:按修改时间倒序、2:按修改时间升序、3:按名称升序、4:按名称倒序
		String orderField = DcsConstants.ORDERED_BY_LAST_UPDATE_TIME;
		if (sort != null) {
			if (DcsConstants.ORDERED_BY_MODIFIED_TIME_DESC == sort) {
				orderField = DcsConstants.ORDERED_BY_LAST_UPDATE_TIME;
			} else if (DcsConstants.ORDERED_BY_MODIFIED_TIME_ASC == sort) {
				orderField = DcsConstants.ORDERED_BY_LAST_UPDATE_TIME;
			} else if (DcsConstants.ORDERED_BY_POLICY_NAME_ASC == sort) {
				orderField = DcsConstants.ORDERED_BY_POLICY_NAME;
			} else if (DcsConstants.ORDERED_BY_POLICY_NAME_DESC == sort) {
				orderField = DcsConstants.ORDERED_BY_POLICY_NAME;
			} else {
				orderField = DcsConstants.ORDERED_BY_LAST_UPDATE_TIME;
			}
		}

		return orderField;
	}

	/**
	 * 构建orderType
	 *
	 * @param sort
	 * @return
	 */
	private String buildOrderType(Integer sort) {
		// 排序，1:按修改时间倒序、2:按修改时间升序、3:按名称升序、4:按名称倒序
		String orderType = DcsConstants.ORDERED_DESC;
		if (sort != null) {
			if (DcsConstants.ORDERED_BY_MODIFIED_TIME_DESC == sort) {
				orderType = DcsConstants.ORDERED_DESC;
			} else if (DcsConstants.ORDERED_BY_MODIFIED_TIME_ASC == sort) {
				orderType = DcsConstants.ORDERED_ASC;
			} else if (DcsConstants.ORDERED_BY_POLICY_NAME_ASC == sort) {
				orderType = DcsConstants.ORDERED_ASC;
			} else if (DcsConstants.ORDERED_BY_POLICY_NAME_DESC == sort) {
				orderType = DcsConstants.ORDERED_DESC;
			} else {
				orderType = DcsConstants.ORDERED_DESC;
			}
		}

		return orderType;
	}

	/**
	 * 根据用户ID获取用户名；传入一个或多个userId，返回userName
	 *
	 * @param userIds
	 * @return
	 * @throws Exception
	 */
	private String getUserNameByIds(String userIds) {
		if (StringUtils.isEmpty(userIds)) {
			return null;
		}

		Map<String, Set<String>> convertFormData = new HashMap<>(16);
		String[] array = userIds.split(Constants.COMMA);
		for (String userId : array) {
			BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, userId);
		}

		StringBuilder buf = new StringBuilder(Constants.STRING_BLANK);
		if (convertFormData.size() > 0) {
			//获取请求结果
			Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
			// 循环设置Alias或Name的值
			for (String userId : array) {
				String name = BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
						userId);
				buf.append(name).append(Constants.COMMA);
			}
		}

		String names = buf.toString();
		if (names.length() >= 1) {
			names = names.substring(0, names.length() - 1);
		}

		return names;
	}
}
